package example.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSONObject;
import example.Exception.DepartmentNoMatchFoundException;
import example.common.Constant;
import example.common.Temp;
import example.entity.Department;
import example.entity.SecondmentContentInfo;
import example.entity.SecondmentHeadInfo;
import example.entity.UserInfo;
import example.mapper.DepartmentMapper;
import example.service.ISecondmentContentInfoService;
import example.service.ISecondmentHeadInfoService;
import example.service.IUserInfoService;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

public class BatchReadListener extends AnalysisEventListener<Map<Integer, String>> {
    /**
     * 每隔100条存储数据库，然后清理list ，方便内存回收
     */
    private static final int    BATCH_COUNT = 100;
    /** 存储内容 */
    private final List<Map<Integer, Map<Integer, String>>> content = new ArrayList<>();
    /** 存储表头数据 */
    private Map<Integer, String> headTitleMap = new HashMap<>();

    private final ISecondmentHeadInfoService secondmentHeadInfoService;

    private final ISecondmentContentInfoService secondmentContentInfoService;

    private final IUserInfoService userInfoService;

    private final DepartmentMapper departmentMapper;

    public BatchReadListener(ISecondmentHeadInfoService secondmentHeadInfoService, ISecondmentContentInfoService secondmentContentInfoService, IUserInfoService userInfoService,DepartmentMapper departmentMapper) {
        this.secondmentHeadInfoService = secondmentHeadInfoService;
        this.secondmentContentInfoService = secondmentContentInfoService;
        this.userInfoService = userInfoService;
        this.departmentMapper = departmentMapper;
    }

    /**
     * 每解析一条数据都会调用
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void invoke(Map<Integer, String> data, AnalysisContext context) {
        Map<Integer, Map<Integer, String>> map = new HashMap<>();
        map.put(context.readRowHolder().getRowIndex(), data);
        content.add(map);
        if (content.size() >= BATCH_COUNT) {
            saveContentData();
            saveUserInfo();
            content.clear();
        }
    }

    /**
     * 所有数据解析完成后调用
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void doAfterAllAnalysed(AnalysisContext context) {
        try{
            saveHeadersData();
            saveContentData();
            saveUserInfo();
        }  catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException("用户信息不正确");
        }
    }

    /**
     * 解析表头数据
     * info.add("部别");
     *         info.add("身份号");
     *         info.add("姓名");
     *         info.add("现任职务");  // 职务层级
     *         info.add("衔级");
     *         info.add("职级");
     *         info.add("借调时间");
     **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        List<String> expectedHeaders = Arrays.asList("部别", "身份号", "姓名","现任职务" ,"衔级","职级","借调时间");
        // 检查头字段是否匹配
        boolean isValid = true;
        headTitleMap = headMap;
        for (String expectedHeader : expectedHeaders) {
            if (!headTitleMap.containsValue(expectedHeader)) { // 索引通常从1开始
                isValid = false;
                break;
            }
        }

        // 如果头字段不匹配，则抛出异常或返回失败结果
        if (!isValid) {
            throw new RuntimeException("上传的Excel文件头字段不符合要求！");
        }


        headTitleMap.put(headTitleMap.size(),"借调起止时间");
    }

    /**
     * 把表头数据存储到数据库
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveHeadersData() {
        int exists = secondmentHeadInfoService.checkSecondmentIdExists(Temp.secondmentId);
        if (exists == 0){
            SecondmentHeadInfo secondmentHeadInfo = new SecondmentHeadInfo();
            secondmentHeadInfo.setSecondmentId(Temp.secondmentId);
            secondmentHeadInfo.setHeaders(JSONObject.toJSONString(headTitleMap).replaceAll("\\\\n", ""));
            secondmentHeadInfoService.save(secondmentHeadInfo);
        }
    }


    public Map<String, Integer> mapInfo() {
        Map<String, Integer> map = new HashMap<>();
        Set<String> info = new HashSet<>();
        info.add("部别");
        info.add("身份号");
        info.add("姓名");
        info.add("现任职务");  // 职务层级
        info.add("衔级");
        info.add("职级");
        info.add("借调时间");
        for (Integer index : headTitleMap.keySet()) {
            String value = headTitleMap.get(index);
            if (info.contains(value)) {
                map.put(value, index);
            }
        }
        return map;
    }

    /**
     * 把内容存储到数据库
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveContentData() {
        Map<String, Integer> map = mapInfo();
        List<String> departmentList = departmentMapper.listDepartmentNames();
        for (Map<Integer, Map<Integer, String>> line : content) {
            SecondmentContentInfo secondmentExcelInfo = new SecondmentContentInfo();
            secondmentExcelInfo.setSecondmentId(Temp.secondmentId);
            for (Integer rowNum : line.keySet()) {
                Map<Integer, String> m = line.get(rowNum);
                Integer departmentName = map.get("部别");
                if (departmentName != null) {
                    String Name = containsAny(m.get(departmentName),departmentList);
                    m.put(departmentName,Name);
                    secondmentExcelInfo.setDepartmentName(Name);
                }
                Integer name = map.get("姓名");
                if (name != null) {
                    secondmentExcelInfo.setUserName(m.get(name));
                }
                Integer userId = map.get("身份号");
                if (userId != null) {
                    secondmentExcelInfo.setUserId(m.get(userId));
                }
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
                String currentDate = sdf.format(new Date());
                secondmentExcelInfo.setSecondmentDate(currentDate);
                Integer lastTime = map.get("借调时间");
                if (lastTime != null) {
                    secondmentExcelInfo.setSecondmentLastTime(m.get(lastTime));
                }
                // 未处理 同意 不同意
                secondmentExcelInfo.setState("未处理");
                secondmentExcelInfo.setFieldsValue(JSONObject.toJSONString(m).replaceAll("\\\\n", ""));
            }
            int exists = secondmentContentInfoService.checkSecondmentContentExists(secondmentExcelInfo);
            if (exists == 0){
            secondmentContentInfoService.save(secondmentExcelInfo);}
        }
    }
    public  String containsAny(String s, List<String> substrings) {
        for (String sub : substrings) {
            if (s.contains(sub)) {
                return sub;
            }
        }

        throw new RuntimeException("部门名称不匹配");
    }
    /**
     * 保存用户信息
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveUserInfo() {
        Map<String, Integer> map = mapInfo();
        for (Map<Integer, Map<Integer, String>> line : content) {
            UserInfo userInfo = new UserInfo();
            List<String> departmentList = departmentMapper.listDepartmentNames();
            for (Integer rowNum : line.keySet()) {
                Map<Integer, String> m = line.get(rowNum);
                Integer departmentName = map.get("部别");
                if (departmentName != null) {
                    String Name = containsAny(m.get(departmentName),departmentList);
                    userInfo.setDepartmentName(Name);
                }
                Integer name = map.get("姓名");
                if (name != null) {
                    userInfo.setName(m.get(name));
                }
                Integer userId = map.get("身份号");
                if (userId != null) {
                    userInfo.setUserId(m.get(userId));
                }
                Integer job = map.get("现任职务");
                if (job != null) {
                    userInfo.setJob(m.get(job));
                }
                Integer partyLevel = map.get("衔级");
                if (partyLevel != null) {
                    userInfo.setPartyLevel(m.get(partyLevel));
                }
                Integer jobLevel = map.get("职级");
                if (jobLevel != null) {
                    userInfo.setJobLevel(m.get(jobLevel));
                }
            }
            UserInfo user = userInfoService.get(userInfo);
            if (user!=null){
                //如果用户id相同，姓名不同或部门不同不允许导入
                if (!userInfo.getName().equals(user.getName())||!userInfo.getDepartmentName().equals(user.getDepartmentName())){
                    throw new RuntimeException("用户信息出错，请检查用户ID和姓名是否对应");
                }
            } else{
                userInfoService.save(userInfo);
            }
        }
    }
}